package cn.itsource.article.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import cn.itsource.article.domain.ArticleType;
import cn.itsource.article.mapper.ArticleTypeMapper;
import cn.itsource.article.query.ArticleTypeQuery;
import cn.itsource.article.service.IArticleTypeService;
import cn.itsource.org.domain.User;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
public class ArticleTypeServiceImpl implements IArticleTypeService {
    @Autowired
    private ArticleTypeMapper articleTypeMapper;

    @Override
    @Transactional
    @CacheEvict(cacheNames = "cache_article_typle",key = "'tree_article_type'")
    public void save(ArticleType articleType) {
        if(articleType.getId() == null){
            articleTypeMapper.insert(articleType);
        }else {
            articleTypeMapper.updateByPrimaryKeySelective(articleType);
        }
    }

    @Override
    @Transactional
    @CacheEvict(cacheNames = "cache_article_typle",key = "'tree_article_type'")
    public int deleteByPrimaryKey(Long id) {
        return articleTypeMapper.deleteByPrimaryKey(id);
    }

    @Override
    public ArticleType selectByPrimaryKey(Long id) {
        return articleTypeMapper.selectByPrimaryKey(id);
    }

    @Override
    public PageInfo<ArticleType> pageInfo(ArticleTypeQuery articleTypeQuery) {
        PageHelper.startPage(articleTypeQuery.getCurrentPage(),articleTypeQuery.getPageSize());
        List<ArticleType> articleTypes = articleTypeMapper.selectAllByQuery(articleTypeQuery);
        return new PageInfo<ArticleType>(articleTypes);
    }

    @Override
    @CacheEvict(cacheNames = "cache_article_typle",key = "'tree_article_type'")
    @Transactional
    public void deleteByCollection(List<ArticleType> articleTypes) {
        articleTypeMapper.deleteByConllection(articleTypes);
    }

    @Override
    public Boolean exist(ArticleType artileType) {
        //根据用户名去数据库查询用户对象
        ArticleType artileTypeByDB = articleTypeMapper.getByName(artileType.getTypeName());
        if (artileType.getId() == null) {
            return artileTypeByDB == null;
        }else{
            //根据用户名去数据库查询
            if (artileTypeByDB == null) {
                return true;
            }else{
                return artileTypeByDB.getId().equals(artileType.getId());
            }
            //值为0： OK的
            //值不为0： 1个       拿到这个对象的值，和前端的id进行匹配，
            // 如果相等ok，如果不相等，就不ok
        }
    }

    @Override
    @Cacheable(cacheNames = "cache_article_typle",key = "'tree_article_type'")
    public List<ArticleType> getTree() {
        //查询到所有的
        List<ArticleType> all = articleTypeMapper.getAll();

         //创建一个空集合 该集合主要是把没有层次接口的文章类型 改为有层次结构，并且响应给前端
        List<ArticleType> treeTypes = new ArrayList<>();
        /*//需要把list转为map 正常写法
        HashMap< Long, ArticleType> map1 = new HashMap<>();
        for (ArticleType articleType : all) {
            map1.put(articleType.getId(),articleType);
        }*/
      //使用鲁昂木 表达式把list转成map
        Map<Long, ArticleType> map = all.stream()
                .collect(Collectors.toMap( ArticleType::getId,  a->a));
       //循环所有的文章类型
        for (ArticleType articleType : all) {
            //如果父级id为空 就证明是一级文章类型
               if(articleType.getParentId() == null){
                  //添加一级
                   treeTypes.add(articleType);
               }else {
                   //如果父级id不为空 那么就说明其有父级 为二级或者n级
                   //拿到父级类型对象
                   ArticleType parentArticleType = map.get(articleType.getParentId());
                   //把儿子装进去
                   parentArticleType.getChildren().add(articleType);
               }
        }
        return treeTypes;
    }

}
